﻿using Microsoft.Phone.Shell;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

namespace SMARTMobile.WinPhone
{
    public class PhoneRootService : IApplicationService
    {
        private IApplicationService _logger;
        private IApplicationService _navigationManager;
        private IApplicationService _dataSourceManager;
        private IApplicationService _directionWatcher;
        private IApplicationService _pushNotification;

        static PhoneRootService()
        {
            Current = new PhoneApplicationService();
        }

        public event Action<LaunchingEventArgs> Launching;
        public event Action<DeactivatedEventArgs> Deactivated;
        public event Action<ActivatedEventArgs> Activated;
        public event Action<ClosingEventArgs> Closing;

        public static PhoneApplicationService Current
        {
            get;
            private set;
        }

        public static bool IsFirstLaunch
        {
            get
            {
                return !IsolatedStorageSettings.ApplicationSettings.Contains("IsFirstLaunch");
            }
        }

        public void StartService(ApplicationServiceContext context)
        {

            _logger = new LogService();
            _navigationManager = new PageNavigationService(SynchronizationContext.Current);
            _dataSourceManager = new DataSourceService();
            _directionWatcher = LoadService("CumeoCoding.Mobile.WinPhone.GeoCoordinateWatcher", "CumeoCoding.Mobile.WinPhone.DirectionWatcher");
            _pushNotification = LoadService("CumeoCoding.Mobile.WinPhone.PushNotification", "CumeoCoding.Mobile.WinPhone.PushNotificationService");

            // start first because other services depend on it
            _logger.StartService(context);
            // start next, because other services depend on it
            _dataSourceManager.StartService(context);

            _navigationManager.StartService(context);
            if (null != _directionWatcher) _directionWatcher.StartService(context);
            if (null != _pushNotification) _pushNotification.StartService(context);

            Current.Launching += RootService_Launching;
            Current.Activated += RootService_Activated;
            Current.Deactivated += RootService_Deactivated;
            Current.Closing += RootService_Closing;
            Current.StartService(context);
        }

        public void StopService()
        {
            Current.StopService();
            Current.Launching -= RootService_Launching;
            Current.Activated -= RootService_Activated;
            Current.Deactivated -= RootService_Deactivated;
            Current.Closing -= RootService_Closing;

            if (null != _pushNotification) _pushNotification.StopService();
            if (null != _directionWatcher) _directionWatcher.StopService();
            _navigationManager.StopService();

            _dataSourceManager.StopService();
            _logger.StopService(); // stop last because other services depend on it

            _logger = null;
            _navigationManager = null;
            _dataSourceManager = null;
            _directionWatcher = null;
            _pushNotification = null;

            //OnStop();
        }

        private IApplicationService LoadService(string assemblyName, string typeName)
        {
            var parts = Deployment.Current.Parts;
            if (parts.Any(part => part.Source.StartsWith(assemblyName)))
            {
                var assembly = Assembly.Load(assemblyName);
                Type type = assembly.GetType(typeName);

                return Activator.CreateInstance(type, new[] { SynchronizationContext.Current }) as IApplicationService;
            }

            return null;
        }

        #region Event Handlers

        private void RootService_Launching(object sender, LaunchingEventArgs e)
        {
            Debug.WriteLine("Current_Launching");
            if (null != Launching) Launching(e);
        }

        private void RootService_Activated(object sender, ActivatedEventArgs e)
        {
            Debug.WriteLine("RootService_Activated");
            //_dataSourceManager.Resume();
            if (_directionWatcher != null)
            {
                _directionWatcher.StartService(null);
            }

            if (!e.IsApplicationInstancePreserved)
            {
                //ViewModelLocator.Current.Load(Current.State);
            }

            if (null != Activated)
                Activated(e);
        }

        private void RootService_Deactivated(object sender, DeactivatedEventArgs e)
        {
            Debug.WriteLine("RootService_Deactivated");

            if (null != Deactivated) Deactivated(e);
            //DataSourceManager.Current.CleanupSubscription(Guid.Empty);
            //_directionWatcher.StopService();
            //_dataSourceManager.Pause();
        }

        private void RootService_Closing(object sender, ClosingEventArgs e)
        {
            Debug.WriteLine("RootService_Closing");

            if (null != Closing) Closing(e);
            if (!IsolatedStorageSettings.ApplicationSettings.Contains("IsFirstLaunch"))
            {
                IsolatedStorageSettings.ApplicationSettings.Add("IsFirstLaunch", null);
            }
        }

        #endregion
    }
}
